#This script runs all the setup sql in the proper order of execution

#import all modules needed
import os, re, sys, inspect, sqlalchemy
from sqlalchemy import select, create_engine, func
from sqlalchemy.orm import scoped_session, sessionmaker

# add models to sys.path
model_dir = os.path.normpath(os.path.dirname(sys.path[0])+'/models')
if((model_dir in sys.path) == False):
	sys.path.append(model_dir)

from config_model import *

def new_session_from_engine(eng, autocommit=False):
	"""creates a new database session from an engine"""
	return scoped_session(sessionmaker(autocommit=False, autoflush=False, bind=eng))

def new_engine(eng, output=False):
	"""creates a new database engine"""
	return create_engine(eng, echo=output)

def new_profile(_session):
	"""creates a new analysis profile"""
	print "Analysis Profile:\n\n"
	host = raw_input("Database Host (leave blank if no database is being used): ")
	data = raw_input("Data directory (top level data directory for this analysis event): ")

	def_results = os.path.normpath(data+"/results")
	results = raw_input("Results directory [%s]: "%def_results)
	if len(results.strip()) == 0:
		results = def_results

	def_html = os.path.normpath(data+"/results/html")
	html = raw_input("HTML directory [%s]: "%def_html)
	if len(html.strip()) == 0:
		html = def_html
	
	ap = AnalysisProfile(host, data, html, results)
	
	print "\nSummary\n-------\n"
	print "Host: %s" % ap.host
	print "Data Directory: %s" % ap.data_directory
	print "Results Directory: %s" % ap.results_directory
	print "HTML Directory: %s" % ap.html_directory
	
	
	_choice = raw_input("\nDoes this look correct? ")
	if 'y' in _choice.lower():
		_session.add(ap)
		_session.commit()
	
		return ap
	
	return None

def new_driver(_session):
	"""creates a new database driver"""
	from config_model import Driver
	import os
	print "Driver:\n\n"
	drvr = raw_input("Database Driver (ie. sqlite:/// or mysql+mysqldb://): ")
	alias = raw_input("Driver Alias: (ie. python_mysql): ")
	
	drv = Driver(drvr, alias)
	
	print "\nSummary\n-------\n"
	print "Driver: %s" % drv.driver
	print "Driver Alias: %s" % drv.alias
	
	if 'y' in raw_input("\nDoes this look correct [y]? ").lower():
		_session.add(drv)
		_session.commit()
		return drv
	
	return None


cwd = os.getcwd()
# print cwd
os.chdir(sys.path[0])
# print os.getcwd()

## create engine
engine = new_engine("sqlite:///../../config/config.db", False)


# create all tables in config_model
print "Creating config tables..."
for m in os.listdir(model_dir):
		if m.endswith(".py") and m.startswith('config'):
			
			#import model as Python module
			module = __import__(m.split(".")[0])
			
			# get classes in model script
			for clz in inspect.getmembers(module, inspect.isclass):
				
				## gets the parent class
				clazz = inspect.getmro(clz[1])
				
				## can't be a base class
				if len(clazz) > 0:
					
					# is it a sqlalchemy class
					if clazz[1].__name__ == "Base":
						
						# creates the table from the class
						clazz[0].__table__.create(engine, checkfirst=True)

# initialize drivers table
session = new_session_from_engine(engine)
drivers = [("sqlite:///", "sqlite_file"),
					("mysql+mysqldb://", "python_mysql"),]

print "Loading database drivers..."
from config_model import Driver
for driver, db_uid in drivers:
	drvr = Driver(driver, db_uid)
	
	matches = session.query(Driver).filter(Driver.driver == driver).all()
	if len(matches) > 1:
		for match in matches[1:]:
			session.delete(match)
	elif len(matches) == 0:
		session.add(drvr)

# create inital configuration with default options
options = [("root_user", "root")]
print "Loading default options..."

from config_model import Option
for key, value in options:
	opt = Option(key, value)
	
	matches = session.query(Option).filter(Option.key == key).all()
	if len(matches) > 0:
		continue
	elif len(matches) == 0:
		session.add(opt)

session.commit()

# initial analysis profile
aes = session.query(AnalysisProfile).all()
selected_ae = None

if len(aes) == 0:
	selected_ae = new_profile(session)
else:
	
	while(True):
		
		print "\n Please select the host and data dir for this configuration: "
		print " Or, simply press ENTER to create a new data analysis profile.\n"
		
		for ae in aes:
			print "  %i). %s (%s)" % (ae.id, ae.host, ae.data_directory)
		
		choice = raw_input("\n Enter choice: ")
		choice = choice.strip()
		
		if len(choice) != 0:
			selected_ae = session.query(AnalysisProfile).filter(AnalysisProfile.id == choice).all()
			
			if selected_ae:
				selected_ae = selected_ae[0]
				break
			else:
				continue
			
		else:
			selected_ae = new_profile(session)

			if selected_ae:
				break
			else:
				continue

	print
	print " %s %s" % ("Host:".ljust(25), selected_ae.host)
	print " %s %s" % ("Data directory:".ljust(25), selected_ae.data_directory)
	print " %s %s" % ("Results directory:".ljust(25), selected_ae.results_directory)
	print " %s %s" % ("Html directory:".ljust(25), selected_ae.html_directory)


drvs = session.query(Driver).all()
selected_drv = None

while(True):
	
	print "\n Please select the database driver for this configuration: "
	print " Or, simply press ENTER to create a driver.\n"
	
	for drv in drvs:
		print "  %i). %s (%s)" % (drv.id, drv.driver, drv.alias)
	
	choice = raw_input("\n Enter choice: ")
	choice = choice.strip()
	
	if len(choice) != 0:
		selected_drv = session.query(Driver).filter(Driver.id == choice).all()
		
		if selected_drv:
			selected_drv = selected_drv[0]
			break
		else:
			continue
	else:
		selected_drv = new_driver(session)

		if selected_drv:
			break
		else:
			continue

print
print " %s %s" % ("Alias:".ljust(12), selected_drv.alias)
print " %s %s" % ("Driver:".ljust(12), selected_drv.driver)

while(True):
	
	conf_name = raw_input("\n Enter the name for this configuration: ")
	
	if len(conf_name.strip()) == 0:
		print "\n  The configuration name cannot be blank!"
		continue
	else:
		conf = Config(conf_name, selected_ae.id, selected_drv.id)
		
		if len(session.query(Config).filter(Config.name == conf_name).all()) > 0:
			print " Configuration names must be unique!"
			continue
		
		session.add(conf)
		session.commit()
		break

opt = Option('current_profile', conf_name)

session.add(opt)
session.commit()
session.close()

os.chdir(cwd)

print "\n Done."
